//by k1 2020.8.14 - 2021.4.8
//调用：0 spawn compile preprocessFileLineNumbers "kk_throw.sqf";
//最好还是单独由服务器执行

uiSleep 22; //

if (!isNil "kk_throw_KeyDownEH") exitWith {systemChat "精准投掷: 已有！"};

kk_throw_pv = {
	if (!isNil "kk_throw_KeyDownEH" || {!isNil "kk_throw_NearWeps"}) exitWith {};
	kk_throw_NearWeps = [];
	kk_throw_c4take = true;
	k1_allUnits = {
		private ["_objs", "_obj"];
		_objs = [];
		{
			_obj = agent _x;
			if (alive _obj) then {_objs pushback _obj};
		} forEach agents;
		_objs append allUnits;
		_objs
	};
	kk_throw_addWepPv = {
		kk_throw_addWep = [_mag,_pro];
		publicVariable "kk_throw_addWep";
		if (!isDedicated) then {kk_throw_NearWeps pushback kk_throw_addWep};
		if (_isThrow) then {
			_name = if(isPlayer _unit)then[{format["(%1)",name _unit]},{"[AI]"}];
			kk_throw_DrawWarning = [_mag,_pro,_unit,_name];
			publicVariable "kk_throw_DrawWarning";
			if (!isDedicated) then {kk_throw_DrawWarning spawn kk_throw_Warning};
		};
	};
	0 spawn {
		while {true} do {
			{
				if (local _x && {isNil {_x getVariable "kk_throw_FiredEH"}} && {alive _x} && {_x isKindOf "CaManBase"} && {!(["UAV_AI", typeOf _x] call BIS_fnc_inString)}) then {
					_idx = _x addEventHandler ["Fired", {
						_unit = _this select 0;
						if (local _unit && {count _this > 6}) then {
							_mag = _this select 5;
							_pro = _this select 6;
							if (_this select 1 == "Throw") then [{
								_isThrow = true;
								call kk_throw_addWepPv;
							},{
								if (_this select 1 == "Put" && {_mag isKindOf ["SatchelCharge_Remote_Mag", configFile >> "CfgMagazines"]} && {_mag != "APERSMineDispenser_Mag"}) then {
									if (kk_throw_c4take || {_unit != player}) then {_isThrow = false; call kk_throw_addWepPv};
									if (!isDedicated) then {call kk_throw_putC4};
								};
							}];
						};
					}];
					_x setVariable ["kk_throw_FiredEH", _idx];
					if (_x == player && {isPlayer _x}) then {diag_log text format["kk_throw: %1 add FiredEH idx=%2", name player, _idx]};
				};
			} forEach (call k1_allUnits);
			_t = time + 30;
			waitUntil {time > _t};
		};
	};
	"kk_throw_setVel" addPublicVariableEventHandler {(_this select 1) spawn {params ["_pro", "_vel", "_enOffset", "_pos"]; if (local _pro) then { detach _pro; waitUntil {isNull attachedTo _pro}; if(_enOffset)then{_pro setPosASL _pos}; _pro setVelocity _vel }}};
	
	if (isDedicated) exitWith {};
	
	"kk_throw_hide" addPublicVariableEventHandler {(_this select 1) hideObject true};
	"kk_throw_addWep" addPublicVariableEventHandler {kk_throw_NearWeps pushback (_this select 1)};
	"kk_throw_DrawWarning" addPublicVariableEventHandler {(_this select 1) spawn kk_throw_Warning};
	"kk_throw_PutDir" addPublicVariableEventHandler {(_this select 1) params ["_pro","_dirUp"]; _pro setDir _dirUp};
	
	kk_throw_fatEff	= .4;
	kk_throw_GV0MaxP = .75;
	kk_throw_GV0MaxC = .9;
	kk_throw_Theta2 = 45;
	kk_throw_state = 0;
	kk_throw_fatAdd = .007; //
	kk_throw_Indicator = objNull;
	kk_throw_Indicator2 = objNull;
	kk_throw_Indicator2Pos = [0,0,0];
	kk_throw_attachArr = [];
	kk_throw_take = false;
	kk_throw_offset = false;
	kk_throw_LOD = "FIRE";
	kk_throw_swLOD = false;
	kk_throw_through = true;
	kk_throw_put = false;
	kk_throw_c4attachArr = [];
	//kk_throw_setPutDir = false;
	kk_throw_icoWarning = [""];
	kk_throw_WarningDraw3dIds = [];
	if(isNil "kk_throw_swWarning")then{kk_throw_swWarning = false};
	if(isNil "kk_throw_swWarning2")then{kk_throw_swWarning2 = true};
	
	kk_throw_fatigue = {
		if (isStaminaEnabled player) then {
			_add = if(kk_throwV0 <= 19)then[{kk_throwV0 * kk_throw_fatAdd},{kk_throwV0 * kk_throw_fatAdd * 2}];
			player setFatigue ((getFatigue player) + _add);
		};
	};
	
	kk_throw_attachC4 = {
		params ["_pro","_anim",["_sel",[]]];
		kk_throw_posObj params ["_pos","_insObj"];
		if (_pos distance player > 2) exitWith {player globalChat "距离太远无法放置到指定位置！"};
		if (alive _insObj && {_insObj isKindOf "CaManBase"}) exitWith {player globalChat "不能放到活人身上！"};
		if ([player, screenToWorld [.5,.5]] call kk_dir_deviation > 10) then {player setDir kk_throw_Dir};
		if (_anim) then {player playActionNow "PutDown"; sleep .5};
		if (count _sel == 2) then {kk_throw_c4attachArr = kk_throw_c4attachArr - [_sel]};
		detach _pro;
		_pro setPosASL (AGLToASL _pos);
		_pro attachTo [_insObj];
		_dirUp = (getDir player) - (getDir _insObj);
		_pro setDir _dirUp;
		kk_throw_PutDir = [_pro,_dirUp];
		publicVariable "kk_throw_PutDir";
	};
	
	kk_throw_putC4 = {
		if (kk_throw_put && {_unit == player} && {isNil "kk_throw_DISABLE"} && {kk_throw_state == 1} && {player getVariable ["FAR_once_eh", true]} && {player getVariable ['FAR_isUnconscious',0] == 0} && {lifeState player != "INCAPACITATED"} && {!visibleMap}) then {
			if (kk_throw_PutMod) exitWith {[_mag,_pro] call kk_throw_attach2};
			[_pro,false] spawn kk_throw_attachC4;
		};
	};
	
	kk_throw_Warning = {
		if (kk_throw_swWarning) exitWith {};
		params ["_mag", "_pro", "_unit", "_name"];
		_dis = 150;
		if (player distance _pro > _dis) exitWith {};
		_side = _unit getVariable ["FAR_unit_Side", side _unit];
		_p_side = player getVariable ["FAR_unit_Side", side player];
		if (_pro isKindOf "Grenade" && {_unit == player || {kk_throw_swWarning2 && {_side getFriend _p_side >= .6} && {_p_side getFriend _side >= .6}}} && {alive _pro}) then {
			_time = time + 15;
			_displayName = getText (configFile >> "cfgMagazines" >> _mag >> "displayname");
			_pictureArr = if(kk_throw_icoWarning select 0 == "")then[{[getText (configFile >> "cfgMagazines" >> _mag >> "picture"),[1,1,1,1],.7,0]},{kk_throw_icoWarning}];
			_i = 0;
			_id = "kk_throw_WarningDraw3D_0";
			while {_id in kk_throw_WarningDraw3dIds} do {_i = _i + 1; _id = format["kk_throw_WarningDraw3D_%1",_i]};
			kk_throw_WarningDraw3dIds pushback _id;
			[_id, "onEachFrame", {
				params ["_pro","_displayName","_pictureArr","_dis","_name","_time","_id"];
				_pictureArr params ["_picture","_color","_size","_shadow"];
				//if !() then {_color = [_color select 0,_color select 1,_color select 2,.4]};
				if (alive _pro && {time < _time} && {isNull attachedTo _pro}) then [{
					if ((lineIntersectsSurfaces [AGLToASL positionCameraToWorld [0,0,0], eyePos _pro, player, _pro, true, 1, "VIEW"] isEqualTo []) && {player distance _pro < _dis}) then {
						drawIcon3D [_picture, _color, _pro, _size, _size, 0, format["%1 %2m %3", _displayName, ceil(player distance _pro), _name], _shadow, .025, "PuristaMedium", "center", true];
					};
				},{
					[_id, "onEachFrame"] call BIS_fnc_removeStackedEventHandler;
					kk_throw_WarningDraw3dIds = kk_throw_WarningDraw3dIds - [_id];
				}];
			},[_pro,_displayName,_pictureArr,_dis,_name,_time,_id]] call BIS_fnc_addStackedEventHandler;
		};
	};
	
	kk_dir_deviation = {
		params ["_unit", "_tag"];
		private ["_dir", "_dir2"];
		_dir = _unit getDir _tag;
		_dir2 = getDir _unit;
		_dir = if(_dir < _dir2)then[{_dir + 360 - _dir2},{_dir - _dir2}];	
		if (_dir > 180) then {_dir = _dir - 360};
		_dir = abs _dir;
		_dir
	};
	
	kk_throw_hideEH = {
		if (isNil "kk_throw_global") then [{
			[_this, true] remoteExec ["hideObject", -clientOwner];
		},{
			kk_throw_hide = _this;
			publicVariable "kk_throw_hide";
		}];
	};
	
	kk_throw_AimOffset = {
		switch _this do {
			case 0: {kk_throw_offsetZ = kk_throw_offsetZ + .02; if (kk_throw_offsetZ > 1) then {kk_throw_offsetZ = 1}; kk_throw_offsetX = .2};
			case 1: {kk_throw_offsetZ = kk_throw_offsetZ - .02; if (kk_throw_offsetZ < 0) then {kk_throw_offsetZ = 0}; kk_throw_offsetX = .2};
			case 2: {kk_throw_offsetX = kk_throw_offsetX - .02; if (kk_throw_offsetX < -.3) then {kk_throw_offsetX = -.3}; kk_throw_offsetZ = 0};
			case 3: {kk_throw_offsetX = kk_throw_offsetX + .02; if (kk_throw_offsetX > .7) then {kk_throw_offsetX = .7}; kk_throw_offsetZ = 0};
			case 4: {kk_throw_offsetY = kk_throw_offsetY + .02; if (kk_throw_offsetY > 1) then {kk_throw_offsetY = 1}};
			case 5: {kk_throw_offsetY = kk_throw_offsetY - .02; if (kk_throw_offsetY < -.3) then {kk_throw_offsetY = -.3}};
		};
		kk_throw_Indicator2 attachTo [player, [kk_throw_offsetX,kk_throw_offsetY,kk_throw_offsetZ], "leftshoulder"];
	};
	
	kk_throw_attach = {
		params ["_mag", "_pro"];
		_pro attachTo [player, [-.08,0,0], "leftshoulder"];
		kk_throw_attachArr pushback _this;
		_displayName = getText (configFile >> "cfgMagazines" >> _mag >> "displayname");
		if (_displayName != "") then {player globalChat format["携带拉开的%1", _displayName]};
		_this spawn {_attachThrow = _this select 1; waitUntil {!alive _attachThrow || {isNull attachedTo _attachThrow} || {!(_this in kk_throw_attachArr)} || {!isNull objectParent player}}; detach _attachThrow; kk_throw_attachArr = kk_throw_attachArr - [_this]};
	};
	
	kk_throw_attach2 = {
		params ["_mag", "_pro"];
		_pro attachTo [player, [0,0,0], "lefthand"];
		kk_throw_c4attachArr pushback [_mag,_pro];
		_displayName = getText (configFile >> "cfgMagazines" >> _mag >> "displayname");
		if (_displayName != "") then {player globalChat format["%1拿到手上", _displayName]};
		[_mag,_pro] spawn {_attachC4 = _this select 1; waitUntil {!alive _attachC4 || {isNull attachedTo _attachC4} || {!(_this in kk_throw_c4attachArr)}}; kk_throw_c4attachArr = kk_throw_c4attachArr - [_this]};
	};
	
	kk_throwTake_KeyDownEH = {
		if (isNil "kk_throw_NearWep") exitWith {};
		kk_throw_NearWep params ["_mag", "_pro"];
		if (alive _pro) then {
			player setDir (player getDir _pro);
			player playActionNow "PutDown";
			sleep .5;
			if (_mag isKindOf ["SatchelCharge_Remote_Mag", configFile >> "CfgMagazines"]) then [{kk_throw_NearWep call kk_throw_attach2},{kk_throw_NearWep call kk_throw_attach}];
		};
		kk_throw_NearWep = nil;
	};
	
	kk_throw_KeyDownEH = {
		kk_throw_Theta = kk_throw_Theta2;
		kk_throw_v0Max = 26;
		kk_throw_offsetY = .28;
		kk_throw_setv0Max = nil;
		kk_throw_PutMod = false;
		kk_throw_posObj = [[0,0,0],objNull];
		if (kk_throw_put) then {[format["<t size = '.5' shadow = '1'>爆炸物: %1</t>", if(kk_throw_c4take)then[{"可以拿起"},{"禁止拿起"}]],.1,.43 * safeZoneH + safeZoneY,2,0,0,608] spawn BIS_fnc_dynamicText};
		//if (kk_throw_put && {{_x isKindOf ["SatchelCharge_Remote_Mag", configFile >> "CfgMagazines"] && {_x != "APERSMineDispenser_Mag"}} count magazines player > 0 || {{alive (_x select 1)} count kk_throw_c4attachArr > 0}}) then {[format["<t size = '.5' shadow = '1'>炸药: '%1'</t>", if(kk_throw_setPutDir)then[{"侧放"},{"平放"}]],.1,.43 * safeZoneH + safeZoneY,2,0,0,608] spawn BIS_fnc_dynamicText};
		_Draw3D = addMissionEventHandler ["Draw3D", {
			private ["_str", "_c"];
			if (isNil "kk_throw_Indicator") then {kk_throw_Indicator = objNull};
			if (kk_throw_put) exitWith {
				kk_throw_Dir = player getDir screenToWorld [.5,.5];
				_beg = eyePos player;
				_endV = _beg vectorAdd (getCameraViewDirection player vectorMultiply 100);
				_ins = lineIntersectsSurfaces [_beg, _endV, player, kk_throw_Indicator, true, 1, "FIRE", "FIRE"];
				_pos1 = if(count _ins == 0)then[{_ins = [[nil,nil,objNull]]; screenToWorld [.5,.5]},{ASLtoAGL (_ins select 0 select 0)}];
				_insObj1 = _ins select 0 select 2; //select 3 父对象
				if (!kk_throw_shift) then {kk_throw_posObj = [_pos1,_insObj1]};
				_pos2 = kk_throw_posObj select 0;
				_insObj2 = kk_throw_posObj select 1;
				if ({_x isKindOf ["SatchelCharge_Remote_Mag", configFile >> "CfgMagazines"] && {_x != "APERSMineDispenser_Mag"}} count magazines player == 0 && {{alive (_x select 1)} count kk_throw_c4attachArr == 0}) then [{_str = "没有炸药！"; _c = [1,0,0,1]},{if (_pos2 distance player > 2 && {!kk_throw_PutMod}) then [{_str = "放置炸药（太远！）"; _c = [1,0,0,1]},{if (alive _insObj2 && {_insObj2 isKindOf "CaManBase"} && {!kk_throw_PutMod}) then [{_str = "无法放置！"; _c = [1,0,0,1]},{if (kk_throw_PutMod) then [{_str = "拿在手上（滚轮）"; _c = [0,1,0,1]},{_str = if({alive (_x select 1)} count kk_throw_c4attachArr > 0)then[{"放置炸药"},{"放置炸药（滚轮）"}]; _c = [0,1,0,1]}]}]}]}];
				if (!isNull kk_throw_Indicator) then {kk_throw_Indicator setPosASL (AGLToASL _pos2)};
				drawIcon3D ["a3\ui_f\data\IGUI\Cfg\simpleTasks\interaction_pointer3_ca.paa", _c, _pos2, 2, 2, 0, _str, 0, .035, "PuristaMedium", "center", true];
			};
			_unit = if(kk_throw_offset)then[{kk_throw_Indicator2},{player}];
			_ins = lineIntersectsSurfaces [eyePos _unit, AGLToASL screenToWorld [.5,.5], _unit, kk_throw_Indicator, true, 1, "FIRE", "FIRE"];
			_pos = if(kk_throw_through || {count _ins == 0})then[{kk_throw_through2 = "不穿过"; screenToWorld [.5,.5]},{kk_throw_through2 = "穿过"; ASLtoAGL (_ins select 0 select 0)}];
			_c = if(kk_throw_ctrl)then[{_str = "原版投掷！"; [1,0,0,1]},{_str = "精准投掷！"; [0,1,0,1]}];
			if (kk_throw_mod == 2) then [{_str = "精准投掷！（携带/松开握片）"; _c = [0,1,0,1]},{if(kk_throw_mod == 1 && {count kk_throw_attachArr > 0})then{_str = "精准投掷！（投掷携带）"; _c = [0,1,0,1]}}];
			drawIcon3D ["", _c, screenToWorld [.5,.5], 2, 2, 0, _str, 0, .035, "PuristaMedium", "center", true];
			if ((kk_throw_mod == 1 && {count kk_throw_attachArr > 0}) || {!kk_throw_ctrl && {kk_throw_mod != 2}}) then {
				_v0Max = kk_throw_v0Max;
				_v0Max = _v0Max - (getFatigue player) * kk_throw_fatEff * _v0Max;
				_ehATL = (ASLtoATL eyePos player) select 2;
				if (_ehATL < 1.4) then {_v0Max = _v0Max * (if(_ehATL < .8)then[{kk_throw_GV0MaxP},{kk_throw_GV0MaxC}])};
				_range = _pos distance2D player;
				_a = if(_range > 7)then[{7.81},{if(_range > 1.2)then[{_range},{0}]}];
				if (_ehATL > 140 && {kk_throw_through}) then {_a = 1};
				_v0 = sqrt(_range * _a / sin (2 * kk_throw_Theta));
				if (_v0 > _v0Max || {kk_throw_shift && {!isNil "kk_throw_setv0Max"}}) then {_v0 = _v0Max};
				if (kk_throw_shift && {isNil "kk_throw_setv0Max"}) then {kk_throw_v0Max = _v0; kk_throw_setv0Max = 1};
				if (!kk_throw_shift && {!isNil "kk_throw_setv0Max"}) then {kk_throw_setv0Max = nil; kk_throw_v0Max = 26};
				if (kk_throw_offsetY > .28) then {_v0 = 0}; //
				_v0x = cos kk_throw_Theta * _v0;
				_v0z = sin kk_throw_Theta * _v0;
				kk_throw_Dir = _unit getDir screenToWorld [.5,.5];
				kk_throwVel = [sin kk_throw_Dir * _v0x, cos kk_throw_Dir * _v0x, _v0z];
				kk_throwV0 = _v0;
				_dir = _unit getDir _pos;
				_flyDirSin = sin _dir;
				_flyDirCos = cos _dir;
				_relPos = _unit getPos [1, _dir];
				_sPosx = _relPos select 0;
				_sPosy = _relPos select 1;
				_pATLz = getPosATL player select 2;
				_trayBase = getPosASL player select 2;
				if (kk_throw_offset) then {
					_pATLz = _pATLz + kk_throw_offsetZ;
					_trayBase = _trayBase + kk_throw_offsetZ;
					_beg = eyePos player;
					kk_throw_Indicator2Pos = getPosASL kk_throw_Indicator2;
					_beg set [2, kk_throw_Indicator2Pos select 2];
					_ins = lineIntersectsSurfaces [_beg, kk_throw_Indicator2Pos, player, kk_throw_Indicator2, true, 1, kk_throw_LOD];
					_cor = if(count _ins == 0)then[{[1,1,1,1]},{_insPos = _ins select 0 select 0; _insRelPos = _insPos getPos [-.1, getDir player]; kk_throw_Indicator2Pos = [_insRelPos select 0,_insRelPos select 1,_insPos select 2]; [1,0,0,1]}];
					_ins2 = lineIntersectsSurfaces [eyePos player, _beg, player, kk_throw_Indicator2, true, 1, kk_throw_LOD];
					if (count _ins2 > 0) then {_cor = [1,0,0,1]; _ins2Pos = _ins2 select 0 select 0; kk_throw_Indicator2Pos = [_ins2Pos select 0,_ins2Pos select 1,(_ins2Pos select 2) - .15]; _beg = kk_throw_Indicator2Pos};
					//drawLine3D [ASLToAGL _beg, ASLToAGL kk_throw_Indicator2Pos, [1,0,0,1]];
					//drawLine3D [ASLToAGL eyePos player, ASLToAGL _beg, [0,0,1,1]];
					drawIcon3D ["a3\ui_f\data\IGUI\Cfg\simpleTasks\interaction_pointer3_ca.paa", _cor, _unit, 2, 2, 0];
				};
				_prevtrajATL = [_sPosx,_sPosy,_pATLz + 2]; ////
				_listDraw = [];
				if (!isNull kk_throw_Indicator) then {kk_throw_Indicator setPosASL (AGLToASL _pos)}; //房顶除错
				drawIcon3D ["a3\ui_f\data\IGUI\Cfg\simpleTasks\interaction_pointer3_ca.paa", _c, _pos, 2, 2, 0];
				for "_t" from .1 to 5 step .1 do {
					_dx = _v0x * _t;
					_dy = _v0z * _t - 4.905 * _t ^ 2  +  1.4;
					_newtrajASL = [_sPosx + _flyDirSin * _dx,_sPosy + _flyDirCos * _dx,_trayBase + _dy];
					_newtrajATL = ASLtoATL _newtrajASL;
					_cross = 0;
					if (_newtrajATL select 2 <= 0) then [{_cross = 1},{if!(lineIntersectsSurfaces [ATLtoASL _prevtrajATL, _newtrajASL, _unit, player, true, 1, kk_throw_LOD] isEqualTo [])then{_cross = 2}}];
					_pATL = getPosATL player;
					if (kk_throw_offset) then {_pATL set [2, (_pATL select 2) + kk_throw_offsetZ]};
					_iDim = (((1/(_pATL distance _newtrajATL)) * 24) max 1) min 2.5;
					_col = if(_cross == 0)then[{[1,1,1,1]},{if(_cross == 1)then[{[0,1,0,1]},{[1,0,0,1]}]}];
					if (_cross != 2 && {!(lineIntersectsSurfaces [eyePos _unit, _newtrajASL, _unit, player, true, 1, kk_throw_LOD] isEqualTo [])}) then {_col set [3,.3]};
					_listDraw pushback [_col, ASLtoAGL _newtrajASL, _iDim]; 
					if (_cross > 0) exitWith {};
					_prevtrajATL = _newtrajATL;
				};
				reverse _listDraw;
				_listSel = _listDraw select 0;
				if !((_listSel select 0) isEqualTo [1,0,0,1]) then {_listDraw set [0, [[0,1,0,.5],_listSel select 1,_listSel select 2]]};
				{
					drawIcon3D ["a3\ui_f\data\IGUI\Cfg\simpleTasks\interaction_pointer3_ca.paa", _x select 0, _x select 1, _x select 2, _x select 2, 0];
				} forEach _listDraw;
				_dis = (_listDraw select 0 select 1) distance2D player;
				if(_dis < 1.1)then{_dis = 1};
				[format["<t color='#00FF00' size = '.45' shadow = '1'>%1m</t>", ceil _dis],.043,.489 * safeZoneH + safeZoneY,.05,0,0,602] spawn BIS_fnc_dynamicText;
			};
		}];
		0 spawn {
			deleteVehicle kk_throw_Indicator;
			kk_throw_Indicator = createVehicle ["Sign_Sphere25cm_Geometry_F", [0,0,0], [], 0, "can_collide"];
			kk_throw_Indicator call kk_throw_hideEH;
		};
		_time = time + 50;
		waitUntil {kk_throw_state > 1 || {kk_throw_state == 0} || {!isNull objectParent player} || {count currentThrowable player == 0 && {kk_throw_mod != 1} && {isNil "kk_throw_fuze"} && {!kk_throw_put}} || {!(player getVariable ["FAR_once_eh", true])} || {player getVariable ['FAR_isUnconscious',0] == 1} || {lifeState player == "INCAPACITATED"} || {visibleMap} || {time > _time}};
		deleteVehicle kk_throw_Indicator;
		detach kk_throw_Indicator2;
		deleteVehicle kk_throw_Indicator2;
		removeMissionEventHandler ["Draw3D",_Draw3D];
		if (time > _time || {visibleMap}) then {kk_throw_state = 0};
		if (kk_throw_state == 0) exitWith {};
		0 spawn {_t = time + 3; waitUntil {time > _t || {kk_throw_state == 8}}; kk_throw_state = 0};
	};
	
	kk_throw_KeyUpEH = {
		if (kk_throw_put) exitWith {
			if ({alive (_x select 1)} count kk_throw_c4attachArr > 0 && {!kk_throw_PutMod}) then {
				_sel = kk_throw_c4attachArr select (count kk_throw_c4attachArr - 1);
				_attachC4 = _sel select 1;
				[_attachC4,true,_sel] spawn kk_throw_attachC4;
			};
			kk_throw_state = 8;
		};
		if (kk_throw_mod == 1 && {count kk_throw_attachArr > 0}) exitWith {
			_sel = kk_throw_attachArr select (count kk_throw_attachArr - 1);
			_magazine = _sel select 0;
			_attachThrow = _sel select 1;
			if ([player, screenToWorld [.5,.5]] call kk_dir_deviation > 10) then {player setDir kk_throw_Dir};
			sleep .01;
			detach _attachThrow;
			if (local _attachThrow) then [{if(kk_throw_offset)then{_attachThrow setPosASL kk_throw_Indicator2Pos}; _attachThrow setVelocity kk_throwVel},{kk_throw_setVel = [_attachThrow, kk_throwVel, kk_throw_offset, kk_throw_Indicator2Pos]; publicVariable "kk_throw_setVel"}];
			kk_throw_attachArr = kk_throw_attachArr - [_sel];
			kk_throw_DrawWarning = [_magazine,_attachThrow,player,format["%1 ",name player]];
			publicVariable "kk_throw_DrawWarning";
			kk_throw_DrawWarning spawn kk_throw_Warning;
			call kk_throw_fatigue;
			kk_throw_state = 8;
		};
		if (count currentThrowable player == 0) exitWith {};
		if (!kk_throw_ctrl || {kk_throw_mod == 2}) then {
			kk_throw_removeEH = 1;
			sleep .01;
			_idx = player addEventHandler ["fired", {
				if (count _this > 6) then {
					if (_this select 1 == "Throw") then {
						_pro = _this select 6;
						if (kk_throw_mod == 2) then [{[_this select 5,_pro] call kk_throw_attach},{if(kk_throw_offset)then{_pro setPosASL kk_throw_Indicator2Pos}; _pro setVelocity kk_throwVel; call kk_throw_fatigue}];
					};
				};
				kk_throw_removeEH = 1;
			}];
			kk_throw_removeEH = nil;
			_idx spawn {
				_time = time + 5;
				waitUntil {!isNil "kk_throw_removeEH" || {time > _time}};
				player removeEventHandler ["fired", _this];
				if (!isNil "kk_throw_fuze") then {
					if (count kk_throw_attachArr > 0 && {!kk_throw_put}) then {kk_throw_mod = 1};
					kk_throw_fuze = nil;
				};
			};
		};
		if ([player, screenToWorld [.5,.5]] call kk_dir_deviation > 10) then {player setDir kk_throw_Dir};
		_muzzle = (currentThrowable player) select 1;
		player forceWeaponFire [_muzzle,_muzzle];
	};
	
	kk_throw_addKey = {
		kk_throw_TAB_t = 0;
		kk_throw_T_t = 0;
		kk_throw_WIN_t = 0;
		kk_throw_C_t = 0;
		if (isNil "kk_throw_key") then {kk_throw_key = 36}; //H键
		waitUntil {!isNull (findDisplay 46)};
		kk_throw_KeyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", {
			_cover = switch (_this select 1) do {
				case kk_throw_key: { params ["", "", "_shift", "_ctrl", "_alt"]; kk_throw_shift = _shift; kk_throw_ctrl = _ctrl; kk_throw_alt = _alt; if (isNil "kk_throw_DISABLE" && {isNull objectParent player} && {kk_throw_state == 0} && {count currentThrowable player > 0 || {_alt && {count kk_throw_attachArr > 0}} || {kk_throw_put && {{_x isKindOf ["SatchelCharge_Remote_Mag", configFile >> "CfgMagazines"] && {_x != "APERSMineDispenser_Mag"}} count magazines player > 0 || {{alive (_x select 1)} count kk_throw_c4attachArr > 0}}}} && {player getVariable ["FAR_once_eh", true]} && {player getVariable ['FAR_isUnconscious',0] == 0} && {lifeState player != "INCAPACITATED"} && {!visibleMap}) then { kk_throw_state = 1; kk_throw_offset = false; kk_throw_mod = if(_alt && {count kk_throw_attachArr > 0} && {!kk_throw_put})then[{_displayName = getText (configFile >> "cfgMagazines" >> ((kk_throw_attachArr select (count kk_throw_attachArr - 1)) select 0) >> "displayname"); if(_displayName != "")then{player globalChat format["投掷携带的%1", _displayName]}; 1},{0}]; 0 spawn kk_throw_KeyDownEH; }; if(kk_throw_mod != 1 && {_alt} && {isNil "kk_throw_fuze"})then{kk_throw_fuze = 1; kk_throw_mod = 2; 0 spawn kk_throw_KeyUpEH; 0 spawn {_t = time + 3; waitUntil {time > _t || {isNil "kk_throw_fuze"}}; kk_throw_fuze = nil};}; if(_alt && {kk_throw_state == 2} && {count kk_throw_attachArr > 0})then{kk_throw_state = 8}; false };
				case 20: { if (kk_throw_state == 1 && {time > kk_throw_T_t}) then {if(kk_throw_put)then[{kk_throw_PutMod = !kk_throw_PutMod},{kk_throw_offset = !kk_throw_offset; detach kk_throw_Indicator2; deleteVehicle kk_throw_Indicator2; _str = if(kk_throw_offset)then[{kk_throw_offsetX = .2; kk_throw_offsetY = .28; kk_throw_offsetZ = .34; kk_throw_Indicator2 = createVehicle ["Sign_Sphere10cm_Geometry_F", [0,0,0], [], 0, "can_collide"]; kk_throw_Indicator2 call kk_throw_hideEH; kk_throw_Indicator2 attachTo [player, [kk_throw_offsetX,kk_throw_offsetY,kk_throw_offsetZ], "leftshoulder"]; "开"},{kk_throw_offsetY = .2; "关"}]; [format["<t size = '.5' shadow = '1'>偏移瞄准: %1</t>", _str],.1,.43 * safeZoneH + safeZoneY,1,0,0,608] spawn BIS_fnc_dynamicText}]; kk_throw_T_t = time + .5}; if (_this select 4 && {isNil "kk_throw_DISABLE"} && {kk_throw_take} && {isNull objectParent player} && {player getVariable ["FAR_once_eh", true]} && {player getVariable ['FAR_isUnconscious',0] == 0} && {lifeState player != "INCAPACITATED"} && {!visibleMap} && {alive player}) then {kk_throw_take = false; 0 spawn kk_throwTake_KeyDownEH}; false }; //t,alt+t
				case 15: { if (kk_throw_state == 1 && {time > kk_throw_TAB_t}) then {_str = if(kk_throw_put)then[{kk_throw_c4take = !kk_throw_c4take; format["<t size = '.5' shadow = '1'>爆炸物: %1</t>", if(kk_throw_c4take)then[{"可以拿起"},{"禁止拿起"}]]},{kk_throw_through = !kk_throw_through; format["<t size = '.5' shadow = '1'>障碍物: %1</t>", kk_throw_through2]}]; [_str,.1,.43 * safeZoneH + safeZoneY,1,0,0,608] spawn BIS_fnc_dynamicText; kk_throw_TAB_t = time + .5}; false }; //TAB
				case 19: { if (kk_throw_state == 1) exitWith {kk_throw_state = 7; true}; false }; //R
				case 219: { if (kk_throw_state == 1 && {time > kk_throw_WIN_t}) then {if(kk_throw_put)then[{/*kk_throw_setPutDir = !kk_throw_setPutDir; [format["<t size = '.5' shadow = '1'>炸药: '%1'</t>", if(kk_throw_setPutDir)then[{"侧放"},{"平放"}]],.1,.43 * safeZoneH + safeZoneY,1,0,0,608] spawn BIS_fnc_dynamicText*/},{kk_throw_swLOD = !kk_throw_swLOD; kk_throw_LOD = if(kk_throw_swLOD)then[{"VIEW"},{"FIRE"}]; [format["<t size = '.5' shadow = '1'>LOD: '%1'</t>", kk_throw_LOD],.1,.43 * safeZoneH + safeZoneY,1,0,0,608] spawn BIS_fnc_dynamicText}]; kk_throw_WIN_t = time + .5}; false }; //WIN
				case 17: { if (kk_throw_state == 1 && {kk_throw_offset}) exitWith {0 call kk_throw_AimOffset; true}; false }; //w
				case 31: { if (kk_throw_state == 1 && {kk_throw_offset}) exitWith {1 call kk_throw_AimOffset; true}; false }; //s
				case 30: { if (kk_throw_state == 1 && {kk_throw_offset}) exitWith {2 call kk_throw_AimOffset; true}; false }; //A
				case 32: { if (kk_throw_state == 1 && {kk_throw_offset}) exitWith {3 call kk_throw_AimOffset; true}; false }; //D
				case 16: { if (kk_throw_state == 1 && {kk_throw_offset}) exitWith {4 call kk_throw_AimOffset; true}; false }; //Q
				case 18: { if (kk_throw_state == 1 && {kk_throw_offset}) exitWith {5 call kk_throw_AimOffset; true}; false }; //E
				case 38: { if (_this select 2 && {isNil "kk_throw_DISABLE"} && {time > kk_throw_C_t}) exitWith {kk_throw_put = !kk_throw_put; [format["<t size = '.5' shadow = '1'>模式: %1</t>", if(kk_throw_put)then[{"放置炸药"},{"精准投掷"}]],.1,.43 * safeZoneH + safeZoneY,1,0,0,608] spawn BIS_fnc_dynamicText; kk_throw_C_t = time + .5; true}; false }; //shift+c
				default { false };
			};
			_cover
		}]; //按下
		
		kk_throw_KeyUp = (findDisplay 46) displayAddEventHandler ["KeyUp", {
			if (_this select 1 == kk_throw_key) then { if(kk_throw_state == 7)then{kk_throw_state = 8}; if (isNil "kk_throw_DISABLE" && {isNull objectParent player} && {kk_throw_state == 1} && {count currentThrowable player > 0 || {kk_throw_mod == 1}} && {player getVariable ["FAR_once_eh", true]} && {player getVariable ['FAR_isUnconscious',0] == 0} && {lifeState player != "INCAPACITATED"} && {!visibleMap}) then {kk_throw_state = 2; 0 spawn kk_throw_KeyUpEH}; };
		}]; //松开
		
		/*kk_throw_MouseKeyDown = (findDisplay 46) displayAddEventHandler ["MouseButtonDown", {
			if (_this select 1 == 1) then { if (kk_throw_state == 1) exitWith {kk_throw_state = 7; true}; false }; //右键
		}]; //鼠标按下*/
		
		kk_throw_MouseZChanged = (findDisplay 46) displayAddEventHandler ["MouseZChanged", {
			if (kk_throw_state == 1 && {!kk_throw_put}) then { _str = if(kk_throw_shift)then[{if(_this select 1 > 0)then{kk_throw_v0Max = kk_throw_v0Max + .25}; if(_this select 1 < 0)then{kk_throw_v0Max = kk_throw_v0Max - 1.25}; if(kk_throw_v0Max > 26)then[{kk_throw_v0Max = 26},{if(kk_throw_v0Max < 0)then{kk_throw_v0Max = 0}}]; format["<t size = '.5' shadow = '1'>力度: %1％</t>", round(kk_throw_v0Max*3.846)]},{if(_this select 1 > 0)then{kk_throw_Theta = kk_throw_Theta + kk_throw_Theta * .1}; if(_this select 1 < 0)then{kk_throw_Theta = kk_throw_Theta - kk_throw_Theta * .1}; if(kk_throw_Theta > 75)then[{kk_throw_Theta = 75},{if(kk_throw_Theta < 1)then{kk_throw_Theta = 1}}]; format["<t size = '.5' shadow = '1'>弧度: %1°</t>", (round(kk_throw_Theta*10))/10]}]; [_str,.1,.43 * safeZoneH + safeZoneY,.05,0,0,608] spawn BIS_fnc_dynamicText; };
		}]; //滚轮
	};
	
	0 spawn {
		while {true} do {
			if (isNil "kk_throw_DISABLE" && {count kk_throw_NearWeps > 0} && {isNull objectParent player} && {player getVariable ["FAR_once_eh", true]} && {player getVariable ['FAR_isUnconscious',0] == 0} && {lifeState player != "INCAPACITATED"} && {!visibleMap} && {alive player}) then {
				_dis = 2;
				kk_throw_take = false;
				{
					_x params ["_mag", "_pro"];
					if (alive _pro) then [{
						_dis2 = _pro distance player;
						if (_dis2 < _dis && {isNull attachedTo _pro || {!isPlayer attachedTo _pro}} && {[player, "FIRE", _pro] checkVisibility [eyePos player, eyePos _pro] > 0}) then {
							_dis = _dis2;
							kk_throw_NearWep = _x;
							kk_throw_take = true;
						};
					},{
						kk_throw_NearWeps = kk_throw_NearWeps - [_x];
					}];
				} forEach kk_throw_NearWeps;
				if (kk_throw_take) then {
					_displayName = getText (configFile >> "cfgMagazines" >> (kk_throw_NearWep select 0) >> "displayname");
					[format["<t size = '.6'>拿起地上的 <t color = '#FF0000'>%1<br/><t color='#FFFFFF'>Alt+T键</t>", _displayName],-1,.78 * safeZoneH + safeZoneY,.5,0,0,374] spawn BIS_fnc_dynamicText;
				};
			};
			sleep .2;
		};
	};
	
	_help = {
		_num = profileNamespace getVariable ["kk_throw_helpHint", 0];
		if (_num > 2) exitWith {};
		uiSleep 50;
		["<t color = '#dc143c' size = '.6' align = 'left'>精准投掷: <br/><t color='#FFFFFF'>长按投掷键瞄准（默认H），松开按键投掷.<br/>Ctrl键切换原版投掷，R键取消投掷.<br/>先按投掷键再按Alt键携带和松开握片.<br/>先按Alt键再按投掷键投掷携带物.<br/>TAB键切换瞄准模式，鼠标滚轮调弧度.<br/>T，A，D，W，S，Q，E切换控制偏移瞄准.<br/>Shift+鼠标滚轮调整力度（距离）.<br/>WIN键切换LOD防止曲线被阻挡.<br/>Shift+C切换投掷或者放置炸药.<br/>打开地图画面有详细说明.<br/></t>",.051 + safeZoneX,.43 * safeZoneH + safeZoneY,30,1,0,73932] spawn BIS_fnc_dynamicText;
		profileNamespace setVariable ["kk_throw_helpHint", _num + 1];
	};
	if (didJIP) then [{
		_time = diag_tickTime + 30;
		waitUntil {!isNil "BIS_fnc_init" || {diag_tickTime > _time}};
		if (diag_tickTime > _time || {isNil "kk_throw_global"}) exitWith {0 spawn _help};
		["kk_throw_jip", "onPreloadFinished", {
			0 spawn (_this select 0);
			["kk_throw_jip", "onPreloadFinished"] call BIS_fnc_removeStackedEventHandler;
		}, [_help]] call BIS_fnc_addStackedEventHandler; //进入任务
		
	},{
		0 spawn _help;
	}];
	
	waitUntil {!isNull player};
	/*
	player createDiarySubject ["kk_throw_help", "精准投掷"];
	player createDiaryRecord ["kk_throw_help", ["说明", "<br/>by k1 2021.4.8<br/><br/>长按投掷键瞄准（默认H），松开按键投掷<br/>Ctrl键切换原版投掷，R键取消投掷<br/>先按投掷键再按Alt键携带和松开握片<br/>先按Alt键再按投掷键投掷携带物<br/>T，A，D，W，S，Q，E切换控制偏移瞄准<br/>TAB键切换是否穿过障碍物<br/>鼠标滚轮调整抛物线弧度<br/>Shift+鼠标滚轮调整力度（距离）<br/>WIN键切换LOD防止曲线被阻挡'VIEW'穿透玻璃'FIRE'穿透树叶<br/>第一人称建议调默认弧度到30<br/>Shift+C切换投掷或者放置炸药长按shift锁定当前位置<br/>长按投掷键能用鼠标滚轮连续拿放N个，T键拿到手上<br/>TAB键设置滚轮选项放置的炸药是否可以拿起<br/>游戏设定中的模组选项有按键设置（需挂CBA）<br/><br/><execute expression = 'if (!isNil {kk_throw_KeyDown}) then { {(findDisplay 46) displayRemoveEventHandler _x} forEach [[""KeyDown"", kk_throw_KeyDown],[""KeyUp"", kk_throw_KeyUp],[""MouseZChanged"", kk_throw_MouseZChanged]] }; 0 spawn kk_throw_addKey; _idx = player getVariable [""kk_throw_FiredEH"", -1]; player removeEventHandler [""fired"", _idx]; player setVariable [""kk_throw_FiredEH"", nil]; kk_throw_state = 0; systemChat ""已执行"";'>修复按键失效</execute>  <execute expression = '_str = if(isNil {kk_throw_DISABLE})then[{kk_throw_DISABLE = 1; ""关闭""},{kk_throw_DISABLE = nil; ""开启""}]; systemChat _str;'>精准投掷开关</execute>  <execute expression = '_str = if(count kk_throw_attachArr > 0)then[{player playActionNow ""PutDown""; _sel = kk_throw_attachArr select (count kk_throw_attachArr - 1); _magazine = _sel select 0; _attachThrow = _sel select 1; _displayName = getText (configFile >> ""cfgMagazines"" >> _magazine >> ""displayname""); detach _attachThrow; if (local _attachThrow) then [{_attachThrow setVelocity [0,0,-2]},{kk_throw_setVel = [_attachThrow,[0,0,-2],kk_throw_offset,kk_throw_Indicator2Pos]; publicVariable ""kk_throw_setVel""}]; kk_throw_attachArr = kk_throw_attachArr - [_sel]; if(_displayName == """")then[{""已经放下""},{format[""放下携带的%1"", _displayName]}]},{""操作无效！""}]; player globalChat _str;'>放下携带的</execute>  <execute expression = 'kk_throw_Theta2 = 30; systemChat ""默认弧度: 30"";'>默认弧度: 30°</execute> <execute expression = 'kk_throw_Theta2 = 45; systemChat ""默认弧度: 45"";'>45°（默认）</execute><br/><execute expression = 'kk_throw_swWarning = !kk_throw_swWarning; _str = if(kk_throw_swWarning)then[{""关闭""},{""开启""}]; systemChat _str;'>标示投掷物</execute><br/>"]];
	*/
	if (isServer || {serverCommandAvailable "#kick"}) then {player createDiaryRecord ["kk_throw_help", ["投掷物图标", "<br/><execute expression = 'kk_throw_swWarning2 = true; publicVariable ""kk_throw_swWarning2""; systemChat ""显示友军投掷的"";'>友军（默认）</execute>  <execute expression = 'kk_throw_swWarning2 = false; publicVariable ""kk_throw_swWarning2""; systemChat ""显示自己投掷的"";'>自己</execute><br/>"]]};
	
	call kk_throw_addKey;
	if (isNil "CBA_Settings_fnc_init") exitWith {};
	[
		"kk_throw_keyDebug",
		"CHECKBOX",
		["修复按键功能", "执行后请改回默认值，不然下次开始任务会自动执行此除错操作"],
		"精准投掷",
		false,
		false,
		{ if (kk_throw_keyDebug) then {if (!isNil {kk_throw_KeyDown}) then { {(findDisplay 46) displayRemoveEventHandler _x} forEach [["KeyDown", kk_throw_KeyDown],["KeyUp", kk_throw_KeyUp],["MouseZChanged", kk_throw_MouseZChanged]] }; 0 spawn kk_throw_addKey; _idx = player getVariable ["kk_throw_FiredEH", -1]; player removeEventHandler ["fired", _idx]; player setVariable ["kk_throw_FiredEH", nil]; kk_throw_state = 0; systemChat "已执行"} }
	] call CBA_Settings_fnc_init; //,["MouseButtonDown", kk_throw_MouseKeyDown]
	[
		"kk_throw_swWarning",
		"CHECKBOX",
		["不标示投掷物", "禁止显示投掷物图标"],
		"精准投掷",
		false,
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"kk_throw_swWarning2",
		"LIST",
		["投掷物图标", ""],
		"精准投掷",
		[[true,false],["显示友军投掷的（默认）","显示自己投掷的"],0],
		true,
		{}
	] call CBA_Settings_fnc_init;
	[
		"kk_throw_icoWarning",
		"LIST",
		["切换标示图标", ""],
		"精准投掷",
		[[[""],["a3\ui_f\data\GUI\Cfg\Hints\Grenades_CA.paa",[.8,.14,.14,1],.6,1],["a3\ui_f\data\IGUI\Cfg\WeaponCursors\throw_gs.paa",[.8,.14,.14,1],1,1]],["投掷物图标（默认）","方形手雷图标","小圆圈"],0],
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"kk_throw_key",
		"LIST",
		["修改投掷键", ""],
		"精准投掷",
		[[34,35,36,24,38],["G键","H键","J键","O键","L键"],2],
		false,
		{}
	] call CBA_Settings_fnc_init;
	[
		"kk_throw_Theta2",
		"SLIDER",
		["默认弧度","越小于45对精度影响越大，第一人称建议调到30左右"],
		"精准投掷",
		[1,75,45,0],
		false,
		{}
	] call CBA_Settings_fnc_init;
};
if (isServer) then [{
	kk_throw_global = 1;
	publicVariable "kk_throw_global";
	publicVariable "kk_throw_pv";
	sleep .3;
	remoteExec ["kk_throw_pv",0,true];
	systemChat "添加精准投掷功能（全局）";
},{
	0 spawn kk_throw_pv;
	systemChat "添加精准投掷功能（本地）";
}];




